package com.youtills.resource;

import java.util.*;

/**
 * TODO - !!!doc me!!!
 *
 * @author ravi.chiluveru
 * @since (8/14/2014)
 */
public abstract class BaseResource implements Resource {

    private Long resourceId;
    private final ResourceType resourceType;
    private boolean dirty;
    private boolean immutable;

    private final ResourceAttributeValue<Date> createdDate;
    private final ResourceAttributeValue<Date> modifiedDate;
    private final List<ResourceAttributeValue> attributeValues;
    private List<ResourceAttributeValue> modifiedAttributes;

    private final List<ResourceRelationship> resourceRelationships;
    private List<ResourceRelationship> modifiedRelationships;

    public BaseResource(final ResourceType resourceType){
        this(resourceType, null);
    }

    public BaseResource(final ResourceType resourceType, final Long resourceId){
        super();
        this.resourceId = resourceId;
        this.resourceType = resourceType;
        this.modifiedAttributes = new ArrayList<ResourceAttributeValue>();
        this.modifiedRelationships = new ArrayList<>();
        this.attributeValues = new ArrayList<ResourceAttributeValue>();
        this.resourceRelationships = new ArrayList<>();

        this.createdDate = new ResourceAttributeValue<Date>(this, CommonAttribute.created_date);
        this.modifiedDate = new ResourceAttributeValue<Date>(this, CommonAttribute.modified_date);

    }

    @Override
    public Long getRid() {
        return null;
    }

    @Override
    public Long getResourceType() {
        return resourceType.getResourceType();
    }

    public BaseResource() {
        this(null);
    }

    @Override
    public Long getResourceId() {
        return resourceId;
    }

    void setResourceId(Long resourceId) {
        this.resourceId = resourceId;
    }

    @Override
    public boolean isDirty() {
        return dirty;
    }

    void setDirty(boolean dirty) {
        this.dirty = dirty;
        if(!dirty) {
            this.modifiedAttributes = new ArrayList<ResourceAttributeValue>();
        }
    }

    @Override
    public boolean isImmutable() {
        return immutable;
    }

    //TODO - move to annotation.
    protected abstract String getTableName();

    //TODO - move to annotation.
    protected String getParentResourceIdColumn() {
        return "parent_resource_id";
    }
    //TODO - move to annotation.
    protected String getParentResourceTypeColumn() {
        return "parent_resource_type";
    }
    //TODO - move to annotation.
    protected String getResourceIdColumn() {
        return "resource_id";
    }

    void addModifiedAttribute(ResourceAttributeValue attribute){
        if(!modifiedAttributes.contains(attribute)) {
            modifiedAttributes.add(attribute);
        }
    }

    void addModifiedRelationshipValue(ResourceRelationship resourceRelationship){
        if(!modifiedRelationships.contains(resourceRelationship)) {
            modifiedRelationships.add(resourceRelationship);
        }
    }

    public List<ResourceAttributeValue> getAttributeValues() {
        return Collections.unmodifiableList(this.attributeValues);
    }

    List<ResourceAttributeValue> getModifiedAttributes() {
        return modifiedAttributes;
    }

    List<ResourceRelationship> getModifiedRelationships() {
        return this.modifiedRelationships;
    }

    public Date getCreatedDate() {
        return createdDate.getValue();
    }

    public Date getModifiedDate() {
        return createdDate.getValue();
    }

    void setCreatedDate(Date createdDate) {
        this.createdDate.setValue(createdDate);
    }

    void setModifiedAt(Date modifiedDate) {
        this.createdDate.setValue(modifiedDate);
    }

    void addAttribute(ResourceAttributeValue resourceAttribute) {
        attributeValues.add(resourceAttribute);
    }

    void addResourceRelationship(ResourceRelationship resourceRelationship) {
        resourceRelationships.add(resourceRelationship);
    }

    List<ResourceRelationship> getResourceRelationships() {
        return resourceRelationships;
    }

    @Override
    public String toString() {
        return resourceType + "..." + resourceId;
    }
}
